#!/bin/sh

###############################################################################
#
# Name: yum-repo-sync
# Summary: Synchronize YUM repository
# License: GPL
# Site: http://www.dotsharp.com.br/softwares/yum-repo-sync-english.html
# Download: http://www.dotsharp.com.br/download/yum-repo-sync-2.0.tar.gz
# Version: 2.0
# Updates:
# 06/08/2006 by Rodrigo Luis Silva
# 03/27/2008 by Erez Hadad
# 01/18/2011 by Rodrigo Luis Silva
#
# Author: Rodrigo Luis Silva
# email: rsilva.14@gmail.com
# site: http://www.dotsharp.com.br
#
# Modified: Erez Hadad
# email: erez.hadad@gmail.com
#
###############################################################################

###############################################################################
#
# This file is part of yum-repo-sync.
#
# yum-repo-sync is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# yum-repo-sync is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with yum-repo-sync.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################

###############################################################################
# Repository configuration is stored in /etc/sysconfig/yum-repo-sync
###############################################################################

if [ -f /etc/sysconfig/yum-repo-sync ]; then
	. /etc/sysconfig/yum-repo-sync
else
	echo "ERROR: Could not find /etc/sysconfig/yum-repo-sync"
	exit -1
fi

ERROR="false"

which --skip-alias createrepo 1>/dev/null 2>/dev/null
if [ $? == 1 ]; then
	echo "ERROR: Could not find program 'createrepo' for repository indexing "
	ERROR="true"
fi

which --skip-alias rsync 1>/dev/null 2>/dev/null
if [ $? == 1 ]; then
	echo "ERROR: Could not find program 'rsync' for repository synchronization "
	ERROR="true"
fi

which --skip-alias mktemp 1>/dev/null 2>/dev/null
if [ $? == 1 ]; then
	echo "ERROR: Could not find program 'mktemp' for temporary file generation "
	ERROR="true"
fi

if [ ${ERROR} == "true" ]; then
	echo -e "\nERROR: Could not find the necessary programs to run, please install all the dependencies above.\n"
	exit -2
fi

confnum=0

while [ "x$(eval echo '$'NAME_$confnum)x" != "xx" ]; do
	NAME=$(eval echo '$'NAME_$confnum)
	ENABLE=$(eval echo '$'ENABLE_$confnum | tr 'A-Z' 'a-z')
	VERBOSE=$(eval echo '$'VERBOSE_$confnum | tr 'A-Z' 'a-z')
	UPDATE_DIR=$(eval echo '$'UPDATE_DIR_$confnum)
	UPDATE_SITE=$(eval echo '$'UPDATE_SITE_$confnum)
	EXCLUDE=$(eval echo '$'EXCLUDE_$confnum)
	COMPRESS=$(eval echo '$'COMPRESS_$confnum | tr 'A-Z' 'a-z')
	FUZZY=$(eval echo '$'FUZZY_$confnum | tr 'A-Z' 'a-z')
	SPARSE=$(eval echo '$'SPARSE_$confnum | tr 'A-Z' 'a-z')
	PARTIAL=$(eval echo '$'PARTIAL_$confnum | tr 'A-Z' 'a-z')
	DELETE=$(eval echo '$'DELETE_$confnum | tr 'A-Z' 'a-z')
	DEL_EXCLUDED=$(eval echo '$'DEL_EXCLUDED_$confnum | tr 'A-Z' 'a-z')
	BWLIMIT=$(eval echo '$'BWLIMIT_$confnum)
	RSYNC_OP=$(eval echo '$'RSYNC_OP_$confnum)

	case "${ENABLE}" in
		yes|true|1)	ENABLE="true";;
		no|false|0)	ENABLE="false";;
		*)		ENABLE=${ENABLE_D};;
	esac

	if [ $ENABLE == "false" ]; then
		if [ $VERBOSE_D == "true" ]; then
			echo "Skipping configuration $confnum (${NAME})"
		fi
		confnum=$(($confnum+1))
		continue
	fi

	case "${VERBOSE}" in
		yes|true|1)	VERBOSE="true";;
		no|false|0)	VERBOSE="false";;
		*)		VERBOSE=${VERBOSE_D};;
	esac

	if [ $VERBOSE == "true" ]; then
		echo -e "\n#################### $NAME ####################\n"
	fi

	if [ ${VERBOSE} == "true" ]; then
		echo "Creating temporary files"
	fi
	RSYNC_OUT=`/bin/mktemp /tmp/rsyncout.XXXXX`
	EXCLUDE_FILE=`/bin/mktemp /tmp/exclude.XXXXX`

	# If individual values are not defined, use the default
	if [ "x${BWLIMIT}" == "x" ]; then
		BWLIMIT=${BWLIMIT_D}
	fi
	if [ "x${EXCLUDE}" == "x" ]; then
		EXCLUDE=${EXCLUDE_D}
	fi
	if [ "x${RSYNC_OP}" == "x" ]; then
		RSYNC_OP=${RSYNC_OP_D}
	fi

	if [ "x${BWLIMIT}" != "x" ]; then
		RSYNC_BWLIMIT_OP="--bwlimit=${BWLIMIT}"
	fi

	if [ "x${EXCLUDE}" != "x" ]; then
		echo ${EXCLUDE} | sed 's/,/\n/g' | while read line
		do
			echo ${line} >> ${EXCLUDE_FILE}
		done
	fi

	case "${COMPRESS}" in
		yes|true|1)	COMPRESS="true";;
		no|false|0)	COMPRESS="false";;
		*)		COMPRESS=${COMPRESS_D};;
	esac

	if [ "${COMPRESS}" == "true" ]; then
		RSYNC_COMPRESS_OP="--compress"
	fi

	case "${FUZZY}" in
		yes|true|1)	FUZZY="true";;
		no|false|0)	FUZZY="false";;
		*)		FUZZY=${FUZZY_D};;
	esac

	if [ "${FUZZY}" == "true" ]; then
		RSYNC_FUZZY_OP="--fuzzy"
	fi
	
	case "${PARTIAL}" in
		yes|true|1)	PARTIAL="true";;
		no|false|0)	PARTIAL="false";;
		*)		PARTIAL=${PARTIAL_D};;
	esac

	if [ "${PARTIAL}" == "true" ]; then
		RSYNC_PARTIAL_OP="--partial"
	fi

	case "${SPARSE}" in
		yes|true|1)	SPARSE="true";;
		no|false|0)	SPARSE="false";;
		*)		SPARSE=${SPARSE_D};;
	esac

	if [ "${SPARSE}" == "true" ]; then
		RSYNC_SPARSE_OP="--sparse"
	fi

	case "${DELETE}" in
		yes|true|1)	DELETE="true";;
		no|false|0)	DELETE="false";;
		*)		DELETE=${DELETE_D};;
	esac

	# if FUZZY is set, DELETE should be delete-after to increase fuzzy efficiency
	if [ ${DELETE} == "true" ]; then
		if [ ${FUZZY} == "true" ]; then
			RSYNC_DELETE_OP="--delete-after";
		else
			RSYNC_DELETE_OP="--delete"
		fi;
	fi

	case "${DEL_EXCLUDED}" in
		yes|true|1)	DEL_EXCLUDED="true";;
		no|false|0)	DEL_EXCLUDED="false";;
		*)		DEL_EXCLUDED=${DEL_EXCLUDED_D};;
	esac

	if [ "${DEL_EXCLUDED}" == "true" ]; then
		RSYNC_DEL_EXCLUDED_OP="--delete-excluded"
	fi

	if [ ! -d ${UPDATE_DIR} ]; then
		if [ ${VERBOSE} == "true" ]; then
			echo "Creating target directory: ${UPDATE_DIR} "
		fi
		/bin/mkdir -p ${UPDATE_DIR}
	fi

	RSYNC_CMD="rsync ${RSYNC_OP} ${RSYNC_BWLIMIT_OP} --itemize-changes --exclude-from=${EXCLUDE_FILE} ${RSYNC_COMPRESS_OP} ${RSYNC_FUZZY_OP} ${RSYNC_PARTIAL_OP} ${RSYNC_SPARSE_OP} ${RSYNC_DEL_EXCLUDED_OP} ${RSYNC_DELETE_OP} --archive ${UPDATE_SITE} ${UPDATE_DIR}"

	if [ ${VERBOSE} == "true" ]; then
		echo -e "Initiating repository synchronization\n"
		echo ${RSYNC_CMD}
		${RSYNC_CMD} | /usr/bin/tee ${RSYNC_OUT} 2>&1
	else
		${RSYNC_CMD} >> ${RSYNC_OUT} 2>&1
	fi

	# if repository was changed but repodata was not changed or deleted, re-create repodata
	CHANGE_COUNT=`cat ${RSYNC_OUT} | grep -v -G "^MOTD:" | grep -v -G "^$" | wc -l`
	if [ ${CHANGE_COUNT} != "0" ]; then
		UPD_REPO=`cat ${RSYNC_OUT} | grep "repodata\/" | wc -l`
		if [ ${UPD_REPO} == "0" ] || [ ! -d ${UPDATE_DIR}/repodata ]; then
			if [ ${VERBOSE} == "true" ]; then
				echo -e "\nPossibly missing or inconsistent repodata - regenerating"
			fi
			/usr/bin/createrepo -q ${UPDATE_DIR}
		fi
	fi

	if [ ${VERBOSE} == "true" ]; then
		echo "Removing temporary files"
	fi
	/bin/rm -rf ${RSYNC_OUT} ${EXCLUDE_FILE}

	RAN="true"

	if [ $VERBOSE == "true" ]; then
		echo -e "##################################################\n"
	fi

	confnum=$(($confnum+1))
done

if [ "x${RAN}" == "x" ]; then
	echo -e "\nPlease, edit config file /etc/sysconfig/yum-repo-sync to enable synchronization\n"
fi
